package com.young.cloud.gateway.filter;

import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.netflix.zuul.exception.ZuulException;
import com.young.common.exception.BaseException;
import com.young.common.util.CommonConstants;
import com.young.common.util.Result;
import com.young.common.util.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.slf4j.MDC;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;

/**
 * 异常过滤器
 * Created by Administrator on 2019/12/28 0028.
 */
@Component
public class ExceptionFilter extends ZuulFilter {
    private static final Logger logger = LoggerFactory.getLogger(ExceptionFilter.class);
    @Override
    public String filterType() {
        return "error";
    }

    @Override
    public int filterOrder() {
        return -2;
    }

    @Override
    public boolean shouldFilter() {
        return true;
    }

    @Override
    public Object run() throws ZuulException {
        RequestContext ctx = RequestContext.getCurrentContext();
        //请求
        HttpServletRequest request = ctx.getRequest();
        //响应
        HttpServletResponse response = ctx.getResponse();
        //异常
        Throwable throwable = ctx.getThrowable();
        PrintWriter pw = null;
        try {
            logger.error("[异常filter] Exception URL={}", request.getRequestURL(), throwable);
            response.setCharacterEncoding(CommonConstants.CHARSET);//编码
            response.setContentType("application/json; charset=utf-8");
            pw = response.getWriter();
            Result result = null;
            if (throwable instanceof BaseException) {
                result = Result.build(((BaseException)throwable).getCode(), ((BaseException) throwable).getInfo());
            } else {
                result = Result.build(Result.CodeEnum.SYSTEM_EXCEPTION);
            }
            result.setUnique(MDC.get(CommonConstants.TRACE_KEY));//记录追踪id,方便查日志
            pw.write(result.toString());

            //清除traceId
            MDC.remove(CommonConstants.TRACE_KEY);

            //删除zuul异常
            if (throwable instanceof ZuulException) {
                ctx.remove("throwable");
            }
        } catch (IOException e) {
            logger.error("[异常filter] 响应流写入异常", e);
        } catch (Exception e) {
            logger.error("[异常filter] 异常处理过程中发生异常!!!", e);
        } finally {
            try{
                if(pw!=null)
                    pw.close();
            }catch (Exception e) {
                logger.error("[异常filter] 关闭PrintWriter异常", e);
            }
        }
        return null;
    }
}
